package com.cookman.renderers;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.utils.viewport.FitViewport;
import com.cookman.actions.Action;
import com.cookman.assets.AssetFonts;
import com.cookman.cards.CityCard;
import com.cookman.gameobjects.WorldMap;
import com.cookman.gameobjects.decks.*;
import com.cookman.interfaces.IUIController;
import com.cookman.serviceLocators.ServiceLocator;
import com.cookman.utils.Constants;
import com.cookman.world.entities.Disease;
import com.cookman.world.entities.Player;

import java.util.List;

/**
 * Created by Cookman on 04.04.14.
 */
public class WorldRenderer extends BaseRenderer {

    protected WorldMap worldMap = new WorldMap();

    private CardDeckActor cardDeck = new CardDeckActor();

    private ActionDeckActor actionDeckActor = new ActionDeckActor();

    private DiseaseDeckActor diseaseDeck = new DiseaseDeckActor();

    private PlayerDeckActor playerDeck = new PlayerDeckActor();

    private DiseaseDistributionDeckActor diseaseDistributionDeckActor = new DiseaseDistributionDeckActor();

    public void setPlayerActions(List<Action> playerActions) {
        actionDeckActor.setActions(playerActions);
    }

    public void setDiseaseDistribution(int count) {
        diseaseDistributionDeckActor.setDistribution(count);
    }

    public void showCardDeck(boolean b) {
        cardDeck.setVisible(b);
    }

    public void showCardDeck(boolean b, boolean isMulti, int maxSelected) {
        cardDeck.setVisible(b);
        cardDeck.setMultiSelect(isMulti);
        cardDeck.setMaxSelected(maxSelected);
    }

    public void setPlayerCards(List<CityCard> playerCards) {
        cardDeck.setX(camera.viewportWidth / 2 - cardDeck.getWidth() / 2);
        cardDeck.setY(camera.viewportHeight / 2 - cardDeck.getHeight() / 2);
        cardDeck.setPlayerCards(playerCards);
    }

    public void showPlayerDeck(boolean b) {
        playerDeck.setVisible(b);
    }

    public void setPlayers(List<Player> players) {
        playerDeck.setX(camera.viewportWidth / 2 - playerDeck.getWidth() / 2);
        playerDeck.setY(camera.viewportHeight / 2 - playerDeck.getHeight() / 2);
        playerDeck.setPlayers(players);
    }

    public void showDiseaseDeck(boolean b) {
        diseaseDeck.setVisible(b);
    }

    public void setCityDisease(List<Disease> cityDisease) {
        diseaseDeck.setX(camera.viewportWidth / 2 - cardDeck.getWidth() / 2);
        diseaseDeck.setY(camera.viewportHeight / 2 - cardDeck.getHeight() / 2);
        diseaseDeck.setDiseases(cityDisease);
    }

    public boolean isModalVisible() {
        return cardDeck.isVisible() || diseaseDeck.isVisible() || playerDeck.isVisible();
    }

    public WorldRenderer() {
        init();
    }

    @Override
    protected void init() {
        super.init();

        //map
        camera = new OrthographicCamera(Constants.VIEWPORT_WIDTH,
                Constants.VIEWPORT_HEIGHT);
        camera.position.set(0, 0, 0);
        camera.update();
        //decks
        cameraDeck = new OrthographicCamera(Constants.VIEWPORT_WIDTH,
                Constants.VIEWPORT_HEIGHT);
        cameraDeck.position.set(0, 0, 0);
        cameraDeck.update();

        //city names. map labels
        cameraGUI = new OrthographicCamera(Constants.VIEWPORT_GUI_WIDTH,
                Constants.VIEWPORT_GUI_HEIGHT);
        cameraGUI.position.set(0, 0, 0);
        cameraGUI.setToOrtho(true); // flip y-axis
        cameraGUI.update();

        //fps and stats, unzoomable
        cameraFPS = new OrthographicCamera(Constants.VIEWPORT_GUI_WIDTH,
                Constants.VIEWPORT_GUI_HEIGHT);
        cameraFPS.position.set(0, 0, 0);
        cameraFPS.setToOrtho(true); // flip y-axis
        cameraFPS.update();

        //default stage
        FitViewport viewport = new FitViewport(Constants.VIEWPORT_WIDTH,
                Constants.VIEWPORT_HEIGHT, camera);
        stage = new Stage(viewport);
        stage.addActor(worldMap);
        worldMap.init();

        //stage for user actions/cards deck
        addDecks();

        initaliseInputProcessors();
    }

    private void addDecks() {
        FitViewport viewportDeck = new FitViewport(Constants.VIEWPORT_WIDTH,
                Constants.VIEWPORT_HEIGHT, cameraDeck);

        stageDeck = new Stage(viewportDeck);
        stageDeck.addActor(actionDeckActor);
        stageDeck.addActor(cardDeck);
        stageDeck.addActor(diseaseDeck);
        stageDeck.addActor(playerDeck);
        stageDeck.addActor(diseaseDistributionDeckActor);
        diseaseDistributionDeckActor.setX(Constants.VIEWPORT_WIDTH-2.5f);
        diseaseDistributionDeckActor.setY(Constants.VIEWPORT_HEIGHT - 0.5f);
    }

    @Override
    public void render(float deltaTime) {
        super.render(deltaTime);
        //first draw background
        drawBackground();
        //then connecting lines
        drawShapes();
        //render cities as actors on stage with event handling
        drawCities(deltaTime);
        //draw GUI stuff as Coordinates and city labels
        drawGUI();
        //draw FPS and stats
        drawFPS();
        //draw game decks
        drawDecks(deltaTime);
    }

    private void drawBackground() {
        batch.setProjectionMatrix(camera.combined);
        batch.begin();
        worldMap.render(batch);
        batch.end();
    }

    private void drawCities(float deltaTime) {
        stage.act(deltaTime);
        stage.draw();
    }

    private void drawShapes() {
        //draw connecting lines between cities
        shapeRenderer.setProjectionMatrix(stage.getCamera().combined);
        shapeRenderer.begin(ShapeRenderer.ShapeType.Line);
        shapeRenderer.setColor(0, 0, 0, 1);
        worldMap.renderShape(shapeRenderer);
        actionDeckActor.renderShape(shapeRenderer);
        cardDeck.renderShape(shapeRenderer);
        shapeRenderer.end();
    }

    private void drawGUI() {
        batchGUI.setProjectionMatrix(cameraGUI.combined);
        batchGUI.begin();
        worldMap.renderGUI(batchGUI);
        cardDeck.renderGUI(batchGUI);
        diseaseDeck.renderGUI(batchGUI);
        playerDeck.renderGUI(batchGUI);
        batchGUI.end();
    }

    private void drawFPS() {
        batchGUI.setProjectionMatrix(cameraFPS.combined);
        batchGUI.begin();

        int cx = Gdx.input.getX();
        int cy = Gdx.input.getY();

        float x = WorldRenderer.camera.position.x - WorldRenderer.uratew * (WorldRenderer.cameraGUI.position.x - cx);
        float y = WorldRenderer.camera.position.y + WorldRenderer.urateh * (WorldRenderer.cameraGUI.position.y - cy);

        String sx = cx + "(" + x + ")";
        String sy = Constants.VIEWPORT_GUI_HEIGHT - cy + "(" + y + ")";
        String stat = "";
        IUIController aliceUI = ServiceLocator.getUIController();
        if (aliceUI.getCurrentPlayer() != null) {
            stat = "Player:" + aliceUI.getCurrentPlayer().getRole() + " " + aliceUI.getTurnCounter();
        }

        AssetFonts.font.setColor(Color.BLACK);
        AssetFonts.font.setScale(0.3f);
        AssetFonts.font.draw(batchGUI, sx + "," + sy + ";" + camera.zoom + ";" + stat, 10, 10);
        //AssetFonts.font.draw(batchGUI,stat, 10, 10);
        batchGUI.end();
    }

    private void drawDecks(float deltaTime) {
        stageDeck.act(deltaTime);
        stageDeck.draw();
    }
}
